precision mediump float;

uniform sampler2D s_texture;
uniform sampler2D shadow_texture;

uniform vec3 sun_vector;

varying vec2 aVertexUVs_;
varying vec3 aVertexNormal_;
varying vec4 shadow_coord_;

float unpack_depth(const in vec4 rgba_depth)
{
    const vec4 bit_shift = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);
    float depth = dot(rgba_depth, bit_shift);
    return depth;
}



void main(void) {
    
	vec2 poissonDisk[17];
/*
	poissonDisk[0] = vec2( -0.94201624, -0.39906216 );
	poissonDisk[1] = vec2( 0.94558609, -0.76890725 );
	poissonDisk[2] = vec2( -0.094184101, -0.92938870 );
	poissonDisk[3] = vec2( 0.34495938, 0.29387760 );
*/
	poissonDisk[4] = vec2( -0.4603522, 0.05781902 );
	poissonDisk[5] = vec2( 0.1833, 0.4220 );
	poissonDisk[6] = vec2( -0.2228, -0.6742 );
	poissonDisk[7] = vec2( -0.8902, -0.3428 );
	poissonDisk[8] = vec2( 0.1578, -0.4475 );
	poissonDisk[9] = vec2( -0.2421, 0.7753 );
	poissonDisk[10] = vec2( -0.9265, 0.1625 );
	poissonDisk[11] = vec2( -0.6603, -0.6752 );
	poissonDisk[12] = vec2( -0.6548, 0.4931 );
	poissonDisk[13] = vec2( -0.0618, 0.0944 );
	poissonDisk[14] = vec2( 0.6546, 0.2202 );
	poissonDisk[15] = vec2( 0.3896, 0.9182 );
	
	poissonDisk[0] = vec2( 0.4748, -0.1856 );
	poissonDisk[1] = vec2( 0.7957, 0.5994 );
	poissonDisk[2] = vec2( 0.6307, -0.6544 );
	poissonDisk[3] = vec2( 0.9017, -0.1625 );
	
	poissonDisk[16] = vec2( 0.3083, -0.9192 );
	
	vec4 shad_coord_;
	
	shad_coord_[0] = (shadow_coord_[0]/shadow_coord_[3])* 0.5 + 0.5;
	shad_coord_[1] = (shadow_coord_[1]/shadow_coord_[3])* 0.5 + 0.5;
	shad_coord_[2] = (shadow_coord_[2]/shadow_coord_[3])* 0.5 + 0.5;
	
	float dot_product  = sun_vector[0] * aVertexNormal_[0] + sun_vector[1] * aVertexNormal_[1] + sun_vector[2] * aVertexNormal_[2];
	//vec4 shadow_color = texture2D( shadow_texture, shadow_coord_.xy);
	float visibility = 1.0;
	for (int i=0;i<17;i++){
		float dd = unpack_depth(texture2D( shadow_texture, shad_coord_.xy + poissonDisk[i]/400.0 ))  -  shad_coord_[2];
		if ( dd < - 0.00004 ){
		//if ( unpack_depth(texture2D( shadow_texture, shad_coord_.xy + poissonDisk[i]/400.0 ))  <  shad_coord_[2] - 0.00004 ){
		//if ( unpack_depth(texture2DBilinear( shadow_texture, shadow_coord_.xy + poissonDisk[i]/50.0 ))  <  shadow_coord_[2] -0.00004 ){
			//visibility-=0.2;
			visibility -= clamp((-dd)*2000.0, 0.8, 1.0)*0.2*0.25;
		}
	}
	
	
	//float depth = unpack_depth(shadow_color);
	//if( shadow_coord_[2] < depth - 0.00004 )
	//	dot_product *= 0.2;
		
	dot_product = dot_product * visibility;
	gl_FragColor = vec4( dot_product, dot_product, dot_product, 1.0 ) * texture2D( s_texture, aVertexUVs_ );// + vec4(1.0, aVertexUVs_[0], 0.0, 1.0);
	//gl_FragColor = vec4(shadow_coord_[2]/100000.0);
	//gl_FragColor = (shadow_color + vec4(0.0));// * texture2D( s_texture, aVertexUVs_ );
	}
	
